<?php


namespace app\controller\admin;


use app\common\model\CommonSearchData;
use app\common\service\redis\PoolRedis;
use app\model\AdminStaff;
use app\model\AdminStaffIcCard;
use app\model\AdminStatisticsPeople;
use app\model\AdminStudentDormitory;
use app\model\AdminUser;
use app\util\ExcelHandle;
use app\util\ReturnCode;
use app\util\Tools;
use think\facade\Queue;
use think\facade\Request;
use think\Response;

class StudentDormitory extends Base
{
    public function index() : Response {
        $limit = $this->request->get('size', config('apiadmin.ADMIN_LIST_DEFAULT'));
        $start = $this->request->get('page', 1);
        $school_id = $this->request->get('school_id', $this->userInfo['school_id']);
        $dor_id = $this->request->get('dor_id', -1);
        $dor_stu_id = $this->request->get('dor_stu_id', -1);
        $door_type = $this->request->get('door_type', '');
        $uuid = $this->request->get('uuid', '');
        $water_no = $this->request->get('water_no', '');
        $electric_no = $this->request->get('electric_no', '');
        $sortKey = $this->request->get('sortKey', 'id');
        $order = $this->request->get('order', 'DESC');
        $where = [
            'AdminStudentDormitory.is_delete' => 0
        ];

        $obj = (new AdminStudentDormitory())->alias('AdminStudentDormitory');
        if ($uuid) {
            $obj = $obj->whereLike('uuid', "%{$uuid}%");
        }
        if ($door_type) {
            $obj = $obj->where('door_type', '=', $door_type);
        }
        if ($water_no) {
            $obj = $obj->whereLike('water_no', "%{$water_no}%");
        }
        if ($electric_no) {
            $obj = $obj->whereLike('electric_no', "%{$electric_no}%");
        }
        if ($school_id > 0) {
            $where['AdminStudentDormitory.school_id'] = $school_id;
        }
        if ($dor_id != -1) {
            $where['AdminStudentDormitory.dormitory_id'] = $dor_id;
        }
        if ($dor_stu_id != -1) {
            $where['AdminStudentDormitory.id'] = $dor_stu_id;
        }

        $listObj = $obj->where($where)
            ->with(['dormitory','school'])
            ->append(['door_type_text'])
            ->order('AdminStudentDormitory.'.$sortKey, $order)
            ->paginate(['page' => $start, 'list_rows' => $limit])->toArray();

        return $this->buildSuccess([
            'list'  => $listObj['data'],
            'count' => $listObj['total'],
            'dormitoryList' => CommonSearchData::getDormitory(AdminStudentDormitory::class, $school_id),
            'doorTypeList' => AdminStudentDormitory::DOOR_TYPE_ARR
        ]);
    }

    public function add(): Response {
        $school_id = Request::post('school_id/d');
        $dormitory_id = Request::post('dormitory_id/d');
        $name = Request::post('name/s', '', 'strip_tags');
        $uuid = Request::post('uuid/s', '', 'strip_tags');
        $door_type = Request::post('door_type/s', '', 'strip_tags');
        $water_no = Request::post('water_no/s', '', 'strip_tags');
        $electric_no = Request::post('electric_no/s', '', 'strip_tags');
        if ($uuid != '00:00:00:00:00:00') {
            $exists = AdminStudentDormitory::where([
                'is_delete' => 0,
                'uuid' => $uuid
            ])->find();
            if ($exists) {
                return $this->buildFailed(ReturnCode::DATA_EXISTS, '门锁uuid已经存在');
            }
        }
        $student_dormitory = new AdminStudentDormitory();
        $student_dormitory->name = $name;
        $student_dormitory->school_id = $school_id;
        $student_dormitory->dormitory_id = $dormitory_id;
        $student_dormitory->uuid = $uuid;
        $student_dormitory->door_type = $door_type;
        $student_dormitory->water_no = $water_no;
        $student_dormitory->electric_no = $electric_no;
        if (!$student_dormitory->save()) {
            return $this->buildFailed(ReturnCode::DB_SAVE_ERROR);
        }

        return $this->buildSuccess();
    }

    public function edit(): Response {
        $student_dormitory = (new AdminStudentDormitory())->where([
            'is_delete' => 0,
            'id' => $this->request->post('id')
        ])->find();
        if (!$student_dormitory) {
            return $this->buildFailed(ReturnCode::RECORD_NOT_FOUND, '宿舍楼未找到');
        }

        $school_id = Request::post('school_id/d');
        $dormitory_id = Request::post('dormitory_id/d');
        $name = Request::post('name/s', '', 'strip_tags');
        $uuid = Request::post('uuid/s', '', 'strip_tags');
        $door_type = Request::post('door_type/s', '', 'strip_tags');
        $water_no = Request::post('water_no/s', '', 'strip_tags');
        $electric_no = Request::post('electric_no/s', '', 'strip_tags');
        if ($uuid != '00:00:00:00:00:00') {
            $exists = AdminStudentDormitory::where([
                'is_delete' => 0,
                'uuid' => $uuid
            ])->where('uuid', '<>', $student_dormitory->uuid)->find();
            if ($exists) {
                return $this->buildFailed(ReturnCode::DATA_EXISTS, '门锁uuid已经存在');
            }
        }
        $student_dormitory->name = $name;
        $student_dormitory->school_id = $school_id;
        $student_dormitory->dormitory_id = $dormitory_id;
        $student_dormitory->uuid = $uuid;
        $student_dormitory->door_type = $door_type;
        $student_dormitory->water_no = $water_no;
        $student_dormitory->electric_no = $electric_no;
        if (!$student_dormitory->save()) {
            return $this->buildFailed(ReturnCode::DB_SAVE_ERROR);
        }
        AdminStudentDormitory::resetPool($student_dormitory);
        return $this->buildSuccess();
    }

    public function del(): Response {
        $where['is_delete'] = 0;
        $student_dormitory = (new AdminStudentDormitory())->where([
            'is_delete' => 0,
            'id' => $this->request->get('id')
        ])->find();
        if (!$student_dormitory) {
            return $this->buildFailed(ReturnCode::RECORD_NOT_FOUND, '宿舍未找到');
        }
        $student_dormitory->is_delete = 1;
        $student_dormitory->save();
        return $this->buildSuccess();
    }

    /**
     * @func import
     * @desc 导入宿舍号信息
     * @return \think\Response
     * @Time: 2021/12/17 11:18
     */
    public function upload(): Response  {
        // 获取表单上传文件 例如上传了001.jpg
        $file = request()->file('excel_file');
        $school_id = request()->post('school_id');
        // 上传到本地服务器
        try {
            validate(['image'=>'fileSize:20480|fileExt:xls,xlsx'])
                ->check([$file]);
            $fileExtendName = substr(strrchr($file->getOriginalName(), '.'), 1);
            $filePath = $file->getPathname();
            if (is_file($filePath)){
                $cols = [['1' => 'number'],['2' =>'dormitory'],['3' => 'name'],['4' => 'door_type'],['5' => 'uuid'],['6' => 'water_no'],['7' => 'electric_no']];
                $data = ExcelHandle::importExcel($filePath,$cols,$fileExtendName);

                $redis = PoolRedis::instance();
                $redis->multi(\Redis::PIPELINE);
                foreach ($data as $datum) {
                    $datum['school_id'] = $school_id;
                    $redis->lPush("upload_student_dormitory", serialize($datum));
                }
                $redis->exec();
                Queue::push('app\task\job\UploadSyncHandlerJob@fire', [
                    'model'=> AdminStudentDormitory::class,
                    'action' => 'upload_student_dormitory'
                ]);
            }
            return $this->buildSuccess();
        } catch (\think\exception\ValidateException $e) {
            return $this->buildFailed(ReturnCode::FILE_SAVE_ERROR, $e->getMessage());
        }
    }

    /**
     * @func download
     * @desc 导出文件
     * @return \think\Response
     * @Time: 2021/12/17 11:18
     */
    public function download(): Response  {
        $titles = [['id' => '序号'],['school_name' => '学校名称'],['dormitory_name'=>'宿舍楼名称'],['name'=>'宿舍号'],['uuid'=>'门锁UUID'],['create_time' => '创建时间']];

        $school_id = $this->request->get('school_id', 0);
        $dor_id = $this->request->get('dor_id', -1);
        $dor_stu_id = $this->request->get('dor_stu_id', -1);
        $uuid = $this->request->get('uuid', '');

        try {
            $where = [
                'AdminStudentDormitory.is_delete' => 0
            ];

            $obj = (new AdminStudentDormitory())->alias('AdminStudentDormitory');

            if ($uuid) {
                $obj = $obj->whereLike('AdminStudentDormitory.uuid', "%{$uuid}%");
            }
            if ($school_id > 0) {
                $where['AdminStudentDormitory.school_id'] = $school_id;
            }
            if ($dor_id != -1) {
                $where['AdminStudentDormitory.dormitory_id'] = $dor_id;
            }
            if ($dor_stu_id != -1) {
                $where['AdminStudentDormitory.id'] = $dor_stu_id;
            }

            $listObj = $obj->where($where)->with(['school','dormitory'])
                ->where('AdminStudentDormitory.is_delete', 0)
                ->order('AdminStudentDormitory.create_time', 'DESC')
                ->select()->toArray();
            $exportData = [];
            $len = 1;
            foreach ($listObj as $datum) {
                $datum['name'] .= "\t";
                $datum['uuid'] .= "\t";
                $newItem = array_merge(['id' => $len],$datum);
                array_push($exportData, $newItem);
                $len++;
            }
            ExcelHandle::downLoadExcel('宿舍号信息' . date('YmdHi'), $titles, $exportData);

        } catch (\think\exception\ValidateException $e) {
            return $this->buildFailed(ReturnCode::FILE_SAVE_ERROR, $e->getMessage());
        }
    }

    /**
     * 获取宿舍中人员数据
     * @return Response
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function getStaffList(): Response {
        $school_id = $this->request->get('school_id', $this->userInfo['school_id']);
        $student_dormitory_id = $this->request->get('student_dormitory_id', '');
        if (!$student_dormitory_id) {
            return $this->buildFailed(ReturnCode::INVALID, '请选择宿舍');
        }
        $stu_sub_query = AdminStudentDormitory::where('is_delete', 0)
            ->field('id,name student_dormitory_name,uuid,door_type');
        // 找出当前宿舍管理员
        $stu_sub_query = $stu_sub_query->buildSql();
        $list = AdminStaffIcCard::alias('card')
            ->join([$stu_sub_query => 'sd'], 'sd.id=card.student_dormitory_id')
            ->join(['admin_staff' => 'staff'], 'staff.id=card.staff_id')
            ->where([
                'staff.is_delete' => 0,
                'card.is_delete' => 0,
                'card.student_dormitory_id' => $student_dormitory_id
            ])
            ->order('staff.type','asc')
            ->order('card.ic_card','desc')
            ->order('card.sim_uid','desc')
            ->with(['staff','school'])
            ->append(['staff.type_text'])
            ->hidden(['school_id','create_time','update_time','is_delete'])
            ->select();

        $redis = PoolRedis::instance();
        $distributionKey = AdminStudentDormitory::NO_KEY."{$school_id}:{$student_dormitory_id}";
        $noKey = $distributionKey.':no';
        $noAll = $redis->hGetAll($noKey);
        $no_list = [];
        foreach ($noAll as $index => $item) {
            $no_list[] = $item;
        }
        foreach ($list as $key => &$value) {
            foreach ($noAll as $index => $item) {
                if ($index == $value['id']){
                    $value['number_no'] = $item;
                }
            }
        }
        $poolKey = $distributionKey.':pool';
        $pool_list = $redis->lRange($poolKey, 0, -1);
        return $this->buildSuccess([
            'list' => $list,
            'pool_list' => $pool_list,
            'no_list' => $no_list
        ]);
    }

    /**
     * 重置宿舍编号池
     * https://test-api.gzcyzhxy.com/admin/StudentDormitory/syncStudentDormitory?student_dormitory_id=490
     * https://port.gzcyzhxy.com/admin/StudentDormitory/syncStudentDormitory?student_dormitory_id=490
     * @return Response
     */
    public function syncStudentDormitory(): Response {
        $student_dormitory_id = $this->request->get('student_dormitory_id', '');
        if (!$student_dormitory_id) {
            return $this->buildFailed(ReturnCode::INVALID, '宿舍未找到');
        }
        $where = [
            'is_delete' => 0,
            //'door_type' => 'KD',
            'id' => $student_dormitory_id
        ];

        $list = (new AdminStudentDormitory())->where($where)->select();
        foreach ($list as $student_dormitory) {
            AdminStudentDormitory::resetPool($student_dormitory);
        }
        return $this->buildSuccess();
    }
}